package php.code.routines;

import java.util.ArrayList;
import java.util.List;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import php.PhpFile;
import php.code.Visibility;
import php.code.instructions.Instruction;
import php.code.instructions.Property;
import php.code.instructions.VariableDeclaration;
import utils.titles.Title;

import com.google.common.base.Joiner;

public abstract class PhpClass extends Routine {

	private final String superClassName;
	private final List<String> interfaces = new ArrayList<>();
	private final ObjectProperty<PhpFile> fileProperty = new SimpleObjectProperty<>();

	protected PhpClass(final Title title, final String superClassName) {
		super(title);
		this.superClassName = superClassName;
		block.content.separator("\n\n");
	}

	public Instruction createProperty(final Visibility visibility, final String name, final Object value) {
		return block.content.add(new Property(this, visibility, name, value));
	}

	public Method createMethod(final Visibility visibility, final Title title, final VariableDeclaration... args) {
		return block.content.add(new Method(this, visibility, title, args));
	}

	public Constructor createConstructor(final Visibility visibility, final VariableDeclaration... args) {
		return block.content.add(new Constructor(this, visibility, args));
	}

	@Override
	protected String getSignature() {
		return Joiner.on(" ").skipNulls().join(
				"class",
				getTitle().toUpperCamel(),
				superClassName == null ? null : "extends " + superClassName,
						interfaces.size() == 0 ? null : "implements " + Joiner.on(", ").join(interfaces)
				);
	}

	public void addInterfaces(final String... interfaces) {
		for (final String anInterface : interfaces) {
			if (fileProperty.getValue() == null)
				fileProperty.addListener((observable, oldValue, newValue) -> fileProperty.getValue().use(anInterface));
			else
				fileProperty.getValue().use(anInterface);

			final String[] strings = anInterface.split("\\\\");
			this.interfaces.add(strings[strings.length - 1]);
		}
	}

	protected void setFile(final PhpFile phpFile) {
		fileProperty.setValue(phpFile);
	}

	public PhpFile getFile() {
		return fileProperty.getValue();
	}
}
